OCP์— ๋Œ€ํ•ด

OCP

Open Closed Principal

  • ์ข‹์€ ์ฝ”๋“œ๋ฅผ ๊ฐ€๋ฅด๋Š” ๊ธฐ์ค€.
  • ์ฝ”๋“œ๋ ˆ๋ฒจ, ๋ชจ๋“ˆ๋ ˆ๋ฒจ, ํŒจํ‚ค์ง€๋ ˆ๋ฒจโ€ฆ ์ง€๊ธˆ์€ ์ฝ”๋“œ๋ ˆ๋ฒจ์„ ๋‹ค๋ฃฌ๋‹ค.
  • ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํ•ต์‹ฌ์›์น™

OCP๋ž€?

  • ์ˆ˜์ •์—๋Š” ๋‹ซํ˜€์žˆ๊ณ  ํ™•์žฅ์—๋Š” ์—ด๋ ค์žˆ๋‹ค.
  • ์ฝ”๋“œ์ˆ˜์ •์—๋Š” ๋‹ซํ˜€์žˆ๊ณ , ์ผ€์ด์Šค(switch์˜ ๋ณ‘๋ ฌ์กฐ๊ฑด) ํ™•์žฅ์—๋Š” ์—ด๋ ค์žˆ๋‹ค = switch๋ฌธ์„ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.
  • ๊ธฐ์กด์˜ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์œผ๋ฉด์„œ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๊ฐ€ ๋˜์–ด์•ผ ํ•œ๋‹ค.

์ฝ”๋“œ๋กœ ์•Œ์•„๋ณด์ž

//stringify๋ฅผ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ
const a = [1, 'ab"c', true, undefined, null, _ => 3];
JSON.stringify(a);

๋‹ค์Œ ์ฝ”๋“œ ์ค‘ el๊ฐ์ฒด๋ฅผ ์‚ดํŽด๋ณด์ž.

const stringCheck = [
  [/[\r\n\l]/g, '\\n'],
  [/"/g, '\\"'],
  [/\t/g, '\\t'],
];

const el = {
  number: v => v.toString(),
  boolean: v => v.toString(),
  string: v =>
    `"${stringCheck.reduce((acc, cur) => acc.replace(cur[0], cur[1]), v)}"`,
  stringify(v) {
    return this[typeof v]?.(v) ?? 'null';
  },
};

const arrValidator = arr => {
  if (!Array.isArray(arr)) throw 'invalid array';
};
let EMPTY = {};

const stringify = arr => {
  arrValidator(arr);
  let result = EMPTY;

  if (arr.length === 0) result = '[]';
  else {
    let acc = '',
      i = 0;
    while (i < acc.length) {
      acc + `,${el.stringify(arr[i])}`;
    }
    result = `[${acc.substr(1)}]`;
  }

  if (result === EMPTY) throw 'no processed';
  return result;
};

el๊ฐ์ฒด ์ฝ”๋“œ๋Š” OCP ์›์น™์„ ๋”ฐ๋ž๋‹ค.

const el = {
  number: v => v.toString(),
  boolean: v => v.toString(),
  string: v =>
    `"${stringCheck.reduce((acc, cur) => acc.replace(cur[0], cur[1]), v)}"`,
  stringify(v) {
    return this[typeof v]?.(v) ?? 'null';
  },
};

function ํƒ€์ž…์„ ์ถ”๊ฐ€ํ•œ๋‹ค๊ณ  ํ•ด๋ณด์ž. el๊ฐ์ฒด์— ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค. ์ด ๋•Œ stringify ํ•จ์ˆ˜๋Š” ๊ฑด๋“ค์ง€ ์•Š๋Š”๋‹ค. (OCP ์ค€์ˆ˜)

function: v = 'null';

ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ์ƒ๊ฐํ•  ๋งŒํ•œ switch๋กœ ์ง ๋‹ค๊ณ  ํ•ด๋ณด์ž. ์•„๋ž˜ ์ฝ”๋“œ์—์„œ ๋งŒ์•ฝ function case๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ํ•˜๋ฉด stringify ํ•จ์ˆ˜๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.

const el = {
  stringify(v) {
    switch (typeof v) {
      case number:
        v => v.toString();
        break;
      case boolean:
        v => v.toString();
        break;
      case string:
        v =>
          `"${stringCheck.reduce(
            (acc, cur) => acc.replace(cur[0], cur[1]),
            v
          )}"`;
        break;
      default:
        v = 'null';
    }
    return v;
  },
};

๊ฐ€์žฅ ์‰ฝ๊ฒŒ OCP๋ฅผ ๋‹ฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ผ์šฐํ„ฐ์™€ ๋ผ์šฐํŒ…ํ…Œ์ด๋ธ”์„ ๋งŒ๋“œ๋Š” ๊ฒƒ.

stringCheck ํ•จ์ˆ˜๋„ ๋ผ์šฐํ„ฐ์™€ ๋ผ์šฐํŒ…ํ…Œ์ด๋ธ”๋กœ ์ˆ˜์ •ํ•ด๋ณด์ž. ๋˜ํ•œ ์ด ํ•จ์ˆ˜๋Š” ๋ฐ์ดํ„ฐ์™€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ถ€๋ถ„์ด ๋‹ฌ๋ผ์„œ ํ•œ๊ณณ์œผ๋กœ ๋ญ‰์ณ์ค˜์•ผ ํ•œ๋‹ค.

// ์›๋ž˜ ์ฝ”๋“œ
const stringCheck = [
  [/[\r\n\l]/g, '\\n'],
  [/"/g, '\\"'],
  [/\t/g, '\\t'],
];

const el = {
  number: v => v.toString(),
  boolean: v => v.toString(),
  string: v =>
    `"${stringCheck.reduce((acc, cur) => acc.replace(cur[0], cur[1]), v)}"`,
  stringify(v) {
    return this[typeof v]?.(v) ?? 'null';
  },
};

//stringCheck๋กœ ๋ญ‰์ณค๋‹ค.
const stringCheck = {
  data: [
    [/[\r\n\l]/g, '\\n'],
    [/"/g, '\\"'],
    [/\t/g, '\\t'],
  ],
  convert(v) {
    return this.data.reduce((acc, cur) => acc.replace(cur[0], cur[1]), v);
  },
};

const el = {
  number: v => v.toString(),
  boolean: v => v.toString(),
  string: v => `" ${stringCheck.convert(v)}"`,
  stringify(v) {
    return this[typeof v]?.(v) ?? 'null';
  },
};

convert ํ•จ์ˆ˜๋ฅผ ์ˆ˜์ •์— ๋‹ซํ˜€์žˆ๊ฒŒ ์œ ์ง€ํ•˜๋ฉด์„œ ์ผ€์ด์Šคํ™•์žฅ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ๋” ๋งŒ๋“ค์—ˆ๋‹ค.stringCheck์—์„œ convert๋Š” ๋ผ์šฐํ„ฐ, data๋Š” ๋ผ์šฐํŒ…ํ…Œ์ด๋ธ”์ด๋‹ค.

el๊ฐ์ฒด๋„ ๋ผ์šฐํ„ฐ์™€ ๋ผ์šฐํŒ…ํ…Œ์ด๋ธ”์ด ๊ตฌ๋ถ„๋˜๋„๋ก ์ˆ˜์ •ํ•ด๋ณด์ž.

//์›๋ž˜ ์ฝ”๋“œ
const el = {
  number: v => v.toString(),
  boolean: v => v.toString(),
  string: v =>
    `"${stringCheck.reduce((acc, cur) => acc.replace(cur[0], cur[1]), v)}"`,
  stringify(v) {
    return this[typeof v]?.(v) ?? 'null';
  },
};

// ์ˆ˜์ •ํ•œ ์ฝ”๋“œ
const el = {
  data: {
    number: v => v.toString(),
    boolean: v => v.toString(),
    string: v => `" ${stringCheck.convert(v)}"`,
  },
  stringify(v) {
    return this.data[typeof v]?.(v) ?? 'null';
  },
};

์•„๋ž˜ ์ฝ”๋“œ stringifyํ•จ์ˆ˜๋„ if,else๋ฅผ ์—†์• ๊ณ  ๋ผ์šฐํ„ฐ์™€ ๋ผ์šฐํŒ…ํ…Œ์ด๋ธ”๋กœ ๊ตฌํ˜„ํ•ด๋ณด์ž.

//์›๋ž˜ ์ฝ”๋“œ
const stringify = arr => {
  arrValidator(arr);
  let result = EMPTY;

  if (arr.length === 0) result = '[]';
  else {
    let acc = '',
      i = 0;
    while (i < acc.length) {
      acc + `,${el.stringify(arr[i])}`;
    }
    result = `[${acc.substr(1)}]`;
  }

  if (result === EMPTY) throw 'no processed';
  return result;
};

//์ˆ˜์ •ํ•œ ์ฝ”๋“œ (resultProcess ์ถ”๊ฐ€)
const resultProcess = {
  data: {
    true: arr => '[]',
    false: arr => {
      let acc = '',
        i = 0;
      while (i < acc.length) {
        acc + `,${el.stringify(arr[i])}`;
      }
      return `[${acc.substr(1)}]`;
    },
  },
  process(arr) {
    this.data[arr.length === 0];
  },
};

const stringify = arr => {
  arrValidator(arr);
  let result = EMPTY;

  return resultProcess.process(arr);

  if (result === EMPTY) throw 'no processed';
  return result;
};

์ •๋ฆฌ

  1. ๋ชจ๋“  ์ผ€์ด์Šค(if, switch)๋Š” ๋ฐ˜๋“œ์‹œ ๋ผ์šฐํ„ฐ์™€ ๋ผ์šฐํŒ…ํ…Œ์ด๋ธ”๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ผ์šฐํ„ฐ๋Š” ์ œ์–ด๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค. ๋ผ์šฐํ„ฐ๋Š” ๋ณ€ํ™”์œจ์ด ๋ผ์šฐํŒ…ํ…Œ์ด๋ธ”๋ณด๋‹ค ๋“œ๋ฌธ๋“œ๋ฌธ ๋ฐœ์ƒํ•œ๋‹ค.
  2. ๋ผ์šฐํ„ฐ๋Š” ๋ฐ˜๋“œ์‹œ mandatory์—ฌ์•ผ ํ•œ๋‹ค.

** ์—ญํ• ๋ชจ๋ธ : ์–ด๋–ป๊ฒŒ ์ฝ”๋“œ์˜ ์—ญํ• ์„ ๋‚˜๋ˆŒ ๊ฒƒ์ธ๊ฐ€? ์ •๋‹ต: ๋ณ€ํ™”์œจ

๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ ๋ผ์šฐํ„ฐ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋ฉด OCP๊ฐ€ ๊นจ์ง€๋Š” ๊ฒƒ์ธ๊ฐ€? ์•„๋‹ˆ๋‹ค. ๋ผ์šฐํ„ฐ์˜ ๋กœ์ง์— ๋งž์ถฐ ๋ผ์šฐํŒ…ํ…Œ์ด๋ธ”์ด ์กด์žฌํ•˜๋ฏ€๋กœ ๋ผ์šฐํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉฐ ๋ผ์šฐํŒ…ํ…Œ์ด๋ธ”์„ ์ „๋ฉด๊ฒ€ํ† ํ•ด์•ผ ํ•œ๋‹ค. === ํŠธ๋žœ์ ์…˜

if์˜ ๋‹จ๊ณ„๋ณ„ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ๋ถ„์„ํ•ด์„œ ๋ณ€ํ™”์œจ์— ๋”ฐ๋ผ OCP๋ฅผ ์ค€์ˆ˜ํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์šฐํ„ฐ์™€ ๋ผ์šฐํŒ…ํ…Œ์ด๋ธ”๋กœ ๋ฒˆ์—ญํ•œ๋‹ค. ์™œ? ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์ข‹์•„์ง

๊ฐ•์˜๋งํฌ

์ฝ”๋“œ์Šคํ”ผ์ธ  Programming101 - 3๊ฐ•


Written by@Jiyon Lee
๋œจ๊ฑฐ์šด ์ฝ”๋“œ๋ฅผ ๊ฐ€๋ฅด๋ฉฐ

GitHub